home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Emulators / v2600 / Source.lha / Source / amiga_sound.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  4.1 KB  |  198 lines

  1. /*****************************************************************************
  2. Amiga sound driver for Amiga v2600 by Matthew Stroup.
  3. Allocates channel through OS, then does hardware banging.
  4. For Amiga v2600 v0.7. April 24, 1997.
  5. ******************************************************************************/
  6.  
  7. #include "types.h"
  8. #include "vmachine.h"
  9. #include "tiasound.h"
  10. #include "options.h"
  11. #include "config.h"
  12. #include <stdio.h>
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <proto/exec.h>
  16. #include <hardware/custom.h>
  17. #include <hardware/dmabits.h>
  18. #include <devices/audio.h>
  19.  
  20. /* Could set this up as an option... */
  21. #define SAMPLE_RATE 8192
  22.  
  23. #define AUDIO_CLOCK 31400
  24.  
  25. static int sound_change;
  26.  
  27. #define SINE 0
  28. #define FOURBIT 1
  29. #define FIVEFOURBIT 2
  30. #define FIVEBIT 3
  31. #define NINEBIT 4
  32.  
  33. void stopsound(void);
  34. void clean_up(void);
  35.  
  36. struct MsgPort *replymp = NULL;
  37. struct IOAudio *audio_req = NULL;
  38.  
  39. UBYTE allocation_array[]={0,1,2,4};
  40.  
  41. /* The buffer is too large at one second! */
  42. static unsigned char *sndbuf=0, *bufpt=0;
  43.  
  44. /* Whether sound is found on start up */
  45. static int sound_available;
  46.  
  47. extern struct AudChannel far aud[];
  48. extern UWORD far dmacon;
  49.  
  50. /****************************************************************************/
  51.  
  52. /* Turn on the sound */
  53. void sound_init (void)
  54. {
  55.     if(base_opts.sound)
  56.     {
  57.         if ((replymp=(struct MsgPort *)CreatePort(NULL, 0))==0)
  58.         {
  59.             printf("Could not create audio port!\n");
  60.             clean_up();
  61.             return;
  62.         }
  63.  
  64.         if ((audio_req=(struct IOAudio *)CreateExtIO(replymp,sizeof(struct IOAudio)))==0)
  65.         {
  66.             printf("Not enough memory for audio structure!\n");
  67.             clean_up();
  68.             return;
  69.         }
  70.  
  71.         if (OpenDevice(AUDIONAME,0,(struct IORequest *)audio_req,0))
  72.         {
  73.             printf("Could not open the Audio Device!\n");
  74.             audio_req->ioa_Request.io_Device=NULL;
  75.             clean_up();
  76.             return;
  77.         }
  78.  
  79.         audio_req->ioa_Request.io_Command=ADCMD_ALLOCATE;
  80.         audio_req->ioa_Request.io_Message.mn_Node.ln_Pri=127;
  81.         audio_req->ioa_Request.io_Flags = ADIOF_NOWAIT;
  82.         audio_req->ioa_Data=allocation_array;
  83.         audio_req->ioa_Length=sizeof(allocation_array);
  84.         BeginIO((struct IORequest *)audio_req);
  85.  
  86.         if (WaitIO((struct IORequest *)audio_req))
  87.         {
  88.             printf("Sound channel not available!\n");
  89.             clean_up();
  90.             return;
  91.         }
  92.  
  93.         if (audio_req->ioa_Request.io_Unit!=0)
  94.         {
  95.             printf("First sound channel not available!\n");
  96.             clean_up();
  97.             return;
  98.         }
  99.  
  100.         if ((sndbuf=(unsigned char *)AllocMem(AUDIO_CLOCK, MEMF_CHIP|MEMF_CLEAR))==NULL)
  101.         {
  102.             printf("Not enough memory for sound buffer!\n");
  103.             return;
  104.         }
  105.  
  106.         sound_available=1;
  107.  
  108.         if (Verbose) printf("Sound driver initialized\n");
  109.  
  110.         bufpt=sndbuf;
  111.  
  112.         Tia_sound_init(AUDIO_CLOCK, SAMPLE_RATE);
  113.     }
  114. }
  115.  
  116. void sound_update(void)
  117. {
  118.     if(sound_available)
  119.     {
  120.         if(sound_change)
  121.         {
  122.             dmacon=DMAF_AUD0;
  123.             Tia_process(bufpt, SAMPLE_RATE);
  124.             aud[0].ac_ptr=(unsigned short *)sndbuf;
  125.             aud[0].ac_len=SAMPLE_RATE;
  126.             aud[0].ac_per=437;
  127.             aud[0].ac_vol=64;
  128.             dmacon=DMAF_SETCLR|DMAF_AUD0;
  129.             bufpt=sndbuf;
  130.             sound_change=0;
  131.         }
  132.     }
  133. }
  134.  
  135. /* Turn off the sound */
  136. void sound_close (void)
  137. {
  138.     clean_up();
  139.     if (sound_available)
  140.     {
  141.             dmacon=DMAF_AUD0;
  142.             if (sndbuf) FreeMem(sndbuf, AUDIO_CLOCK);
  143.     }
  144. }
  145.  
  146. void sound_freq(int channel, UBYTE freq)
  147. {
  148.     static BYTE last[2];
  149.     if(sound_available && last[channel]!=freq)
  150.     {
  151.         Update_tia_sound(0x17 + channel, freq);
  152.         sound_change=1;
  153.         last[channel]=freq;
  154.     }
  155. }
  156.  
  157. void sound_volume(int channel, UBYTE vol)
  158. {
  159.     static BYTE last[2];
  160.     if(sound_available && last[channel]!=vol)
  161.     {
  162.         Update_tia_sound(0x19 + channel, vol);
  163.         sound_change=1;
  164.         last[channel]=vol;
  165.     }
  166. }
  167.  
  168. void sound_waveform(int channel, UBYTE value)
  169. {
  170.     static BYTE last[2];
  171.     if(sound_available && last[channel]!=value)
  172.     {
  173.         Update_tia_sound(0x15 + channel, value);
  174.         sound_change=1;
  175.         last[channel]=value;
  176.     }
  177. }
  178.  
  179. void clean_up(void)
  180. {
  181.     if (audio_req && !(audio_req->ioa_Request.io_Error))
  182.     {
  183.         audio_req->ioa_Request.io_Command = ADCMD_FREE;
  184.         DoIO((struct IORequest *)audio_req);
  185.     }
  186.  
  187.     if (audio_req && audio_req->ioa_Request.io_Device)
  188.         CloseDevice((struct IORequest *)audio_req);
  189.  
  190.     if (replymp)
  191.     {
  192.         while (GetMsg(replymp)) sound_change=1;
  193.         DeletePort(replymp);
  194.     }
  195.  
  196.     if(audio_req) DeleteExtIO((struct IORequest *)audio_req);
  197. }
  198.